package com.hcss.common.springmvc;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.method.annotation.ModelAttributeMethodProcessor;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import java.util.ArrayList;
import java.util.List;

/**
 * @desc mvc配置
 * 静态资源访问
 * 数据转化conventer
 * @author Administrator
 * @date 2018年6月27日 上午10:33:18
 * @company 浙江鸿程计算机系统有限公司 
 */
@Configuration
public class HcssWebMvcConfig extends WebMvcConfigurerAdapter {
    public static final SerializerFeature WRITE_DATE_USE_DATE_FORMAT = SerializerFeature.WriteDateUseDateFormat;

    @Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/assets/**").addResourceLocations("/assets/");
        registry.addResourceHandler("/**/js/*.js", "/**/css/*.css").addResourceLocations("/WEB-INF/jsp/");
        super.addResourceHandlers(registry);
	}
	@Bean
	public StringHttpMessageConverter getStringHttpConverter() {
		StringHttpMessageConverter converter = new StringHttpMessageConverter();
		List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
		supportedMediaTypes.add(MediaType.parseMediaType("text/html;charset=UTF-8"));
		supportedMediaTypes.add(MediaType.parseMediaType("text/plain;charset=UTF-8"));
		supportedMediaTypes.add(MediaType.parseMediaType("application/x-www-form-urlencoded;charset=UTF-8"));
		supportedMediaTypes.add(MediaType.parseMediaType("application/json;charset=UTF-8"));
		converter.setSupportedMediaTypes(supportedMediaTypes);
		return converter;
	}
	
	@Bean
	public FastJsonHttpMessageConverter getFastJsonConverter() {
		FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
		FastJsonConfig config = new FastJsonConfig();
        JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
		SerializerFeature[] serializerFeatures = new SerializerFeature[] {
				SerializerFeature.QuoteFieldNames, 
				SerializerFeature.WriteNullListAsEmpty,
				SerializerFeature.DisableCircularReferenceDetect,
				SerializerFeature.WriteMapNullValue, 
				SerializerFeature.WriteNullNumberAsZero,
				SerializerFeature.WriteNullStringAsEmpty,
				SerializerFeature.WriteNullBooleanAsFalse,
                SerializerFeature.WriteDateUseDateFormat
		};
		config.setSerializerFeatures(serializerFeatures);
		converter.setFastJsonConfig(config);
		List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
		supportedMediaTypes.add(MediaType.parseMediaType("application/json;charset=UTF-8"));
		converter.setSupportedMediaTypes(supportedMediaTypes);
		return converter;
	}

	@Override
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		converters.clear();
		converters.add(getStringHttpConverter());
		converters.add(getFastJsonConverter());
	}

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET","POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }

    @Override
     public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
         configurer.enable();
	 }

    @Bean
    public BeanPostProcessor jsonAndFormArgumentResolverProcessor() {
        return new BeanPostProcessor() {
            @Override
            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                return bean;
            }

            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

                if (bean instanceof RequestMappingHandlerAdapter) {
                    JsonAndFormArgumentResolver jsonAndFormArgumentResolver = null;
                    ModelAttributeMethodProcessor modelAttributeMethodProcessor = null;
                    RequestResponseBodyMethodProcessor requestResponseBodyMethodProcessor = null;

                    for (HandlerMethodArgumentResolver argumentResolver : ((RequestMappingHandlerAdapter) bean).getArgumentResolvers()) {
                        if (argumentResolver instanceof JsonAndFormArgumentResolver) {
                            jsonAndFormArgumentResolver = (JsonAndFormArgumentResolver) argumentResolver;
                            continue;
                        }
                        if (argumentResolver instanceof RequestResponseBodyMethodProcessor) {
                            requestResponseBodyMethodProcessor = (RequestResponseBodyMethodProcessor) argumentResolver;
                            continue;
                        }
                        if (argumentResolver instanceof ModelAttributeMethodProcessor) {
                            modelAttributeMethodProcessor = (ModelAttributeMethodProcessor) argumentResolver;
                        }
                    }
                    if (jsonAndFormArgumentResolver != null) {
                        jsonAndFormArgumentResolver.setModelAttributeMethodProcessor(modelAttributeMethodProcessor);
                        jsonAndFormArgumentResolver.setRequestResponseBodyMethodProcessor(requestResponseBodyMethodProcessor);
                    }
                }

                return bean;
            }
        };
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new JsonAndFormArgumentResolver());
    }
}
